/*
RECENG.C

Sound record/playback application engine
*/

#include <p_std.h>
#include <p_sys.h>
#include <p_gen.h>
#include <p_file.h>
#include <epoc.h>
#include <record.g>
#include <record.rsg>
#include <hwim.h>
#include <s_.rsg>

#define RECENG_ENVNAME "REC$PREF"
#define RECENG_ENVNAMELEN 8

GLREF_D PR_HWIMMAN * const w_am;

LOCAL_C UINT ConvDurationTo2Ks(UINT tenths)
/*
Convert 10ths of a second to 2Kbyte units
*/
    {
    return((tenths*25+0x3f)>>6);
    }

LOCAL_C INT IsDeviceSuitable(INT device)
    {
    P_DINFO dinfo;
    TEXT dspec[16];

    if (device!='M')
        {
        p_scpy(&dspec[0],"LOC::M:");
        dspec[P_FSYSNAMESIZE]=device;
        p_dinfo(&dspec[0],&dinfo);
        return((dinfo.mediatype&0xff)==P_FMEDIA_RAM);
        }
    return(TRUE);
    }

LOCAL_C INT DiskToDevice(INT disk)
    {
    if (disk==0)
        return('A');
    if (disk==1)
        return('M');
    if (disk==2)
        return('B');
    }

LOCAL_C VOID CheckSoundCompletion(INT stat)
    {
    if (stat==E_GEN_FAIL)
        hInfoPrint(-SYS_SOUND_DISABLED);
    else
        f_leave(stat);
    }

#pragma METHOD_CALL

METHOD VOID receng_eng_init(PR_RECENG *self,PR_ROOT *hview,UINT mupdate,UINT msound)
    {
    self->receng.prefs.duration=20; /* two seconds */
    self->receng.prefs.disk=1; /* Internal (M:) */
    self->receng.hview=hview;
    self->receng.mupdate=mupdate;
    self->receng.msound=msound;
    self->receng.wvefile=f_new(CAT_RECORD_RECORD,C_WVEFILE);
    self->receng.waveao=f_newsend(CAT_RECORD_RECORD,C_WAVEAO,O_AO_INIT,self,O_ENG_DONE_RECORD,O_ENG_DONE_PLAY);
    }

METHOD TEXT *receng_eng_sense_file(PR_RECENG *self)
    {
    return((TEXT *)p_send2(self->receng.wvefile,O_WVE_SENSE_FNAME));
    }

METHOD INT receng_eng_default_disk(PR_RECENG *self)
/*
Returns the default device letter for new recordings.
Based on the "dialog" local disk number (0:A, 1:M, 2:B).
Guaranteed to return a suitable disk.
*/
    {
    INT device;
    TEXT fspec[P_FNAMESIZE];

    p_send2(self,O_ENG_SENSE_PREFS);
    device=DiskToDevice(self->receng.prefs.disk); /* try user-specified preference first */
    if (!IsDeviceSuitable(device))
        { /* preference is unsuitable */
        device='M'; /*  fallback if the default device is unsuitable */
        p_getpth(&fspec[0]);
        if (IsDeviceSuitable(fspec[P_FSYSNAMESIZE]))
            device=fspec[P_FSYSNAMESIZE];
        }
    return(device);
    }

METHOD VOID receng_eng_view_update(PR_RECENG *self)
    {
    p_send2(self->receng.hview,self->receng.mupdate);
    }

METHOD INT receng_eng_new_file(PR_RECENG *self,TEXT *pname)
    {
    return(p_send3(self->receng.wvefile,O_WVE_NEW,pname));
    }

METHOD VOID receng_eng_open_file(PR_RECENG *self,TEXT *pname)
    {
    p_send3(self->receng.wvefile,O_WVE_OPEN,pname);
    p_send3(w_am,O_AM_NEW_FILENAME,receng_eng_sense_file(self));
    receng_eng_view_update(self);
    }

METHOD VOID receng_eng_done_record(PR_RECENG *self,INT stat)
    {
    CheckSoundCompletion(stat);
    receng_eng_open_file(self,NULL);
    }

METHOD VOID receng_eng_done_play(PR_RECENG *self,INT stat)
    {
    CheckSoundCompletion(stat);
    receng_eng_view_update(self);
    }

METHOD VOID receng_eng_sound_play(PR_RECENG *self)
    {
    INT v;
    WVEFILE_INFO info;

    p_send2(self,O_ENG_SENSE_PREFS);
    v=0; /* loud */
    if (self->receng.prefs.volume==1)
        v=2; /* medium */
    else if (self->receng.prefs.volume==2)
        v=5; /* quiet */
    p_send3(self->receng.wvefile,O_WVE_SENSE_INFO,&info);
    if (info.duration==0)
        {
        hInfoPrint(NO_DATA_NO_PLAY);
        return;
        }
    p_send4(self->receng.waveao,O_WV_PLAY,p_send2(self->receng.wvefile,O_WVE_SENSE_FNAME),v);
    p_send3(self->receng.hview,self->receng.msound,&info.total);
    }

METHOD VOID receng_eng_sound_record(PR_RECENG *self,UINT duration)
    {
    UINT num2Ks;
    ULONG tenths;
    TEXT *name;

    num2Ks=ConvDurationTo2Ks(duration);
    tenths=num2Ks;
    tenths=(tenths<<6)/25;
    name=(TEXT *)p_send2(self->receng.wvefile,O_WVE_SENSE_FNAME);
    if (name[P_FSYSNAMESIZE]=='M')
        p_delete(name); /* free space for the sound server */
    p_send4(self->receng.waveao,O_WV_RECORD,name,num2Ks);
    p_send3(self->receng.hview,self->receng.msound,&tenths);
    }

METHOD VOID receng_eng_sound_stop(PR_RECENG *self)
    {
    p_send2(self->receng.waveao,O_WV_STOP);
    }

METHOD VOID receng_eng_set_repeats(PR_RECENG *self,UINT repeats,UINT tenths)
    {
    p_send4(self->receng.wvefile,O_WVE_SET_REPEATS,repeats,tenths);
    receng_eng_view_update(self);
    }

METHOD VOID receng_eng_file_info(PR_RECENG *self,WVEFILE_INFO *pi)
    {
    p_send3(self->receng.wvefile,O_WVE_SENSE_INFO,pi);
    }

METHOD RECENG_PREFS *receng_eng_sense_prefs(PR_RECENG *self)
    {
    INT len;
    TEXT bb[P_ENVMAX];

    len=p_getenviron(RECENG_ENVNAME,RECENG_ENVNAMELEN,&bb[0]);
    if (len==sizeof(RECENG_PREFS))
        self->receng.prefs=*(RECENG_PREFS *)&bb[0];
    return(&self->receng.prefs);
    }

METHOD VOID receng_eng_set_prefs(PR_RECENG *self,RECENG_PREFS *new)
    {
    if (!p_bcmp(&self->receng.prefs,sizeof(RECENG_PREFS),new,sizeof(RECENG_PREFS)))
        return; /* no change */
    self->receng.prefs=*new;
    f_leave(p_setenviron(RECENG_ENVNAME,RECENG_ENVNAMELEN,&self->receng.prefs,sizeof(RECENG_PREFS)));
    }
